package cn.zero.wechat.util;

import java.io.InputStream;
import java.io.Writer;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

import cn.zero.wechat.req.WechatMpMessage;
import cn.zero.wechat.resp.BaseMessage;
import cn.zero.wechat.resp.MusicMessage;
import cn.zero.wechat.resp.NewsMessage;
import cn.zero.wechat.resp.TextMessage;


public class MessageUtil {

	public static final String RESP_MESSAGE_TYPE_TEXT = "text";

	public static final String RESP_MESSAGE_TYPE_MUSIC = "music";

	public static final String RESP_MESSAGE_TYPE_NEWS = "news";

	public static final String RESP_MESSAGE_TYPE_IMAGE = "image";

	public static final String REQ_MESSAGE_TYPE_TEXT = "text";

	public static final String REQ_MESSAGE_TYPE_IMAGE = "image";

	public static final String REQ_MESSAGE_TYPE_LINK = "link";

	public static final String REQ_MESSAGE_TYPE_LOCATION = "location";

	public static final String REQ_MESSAGE_TYPE_VOICE = "voice";

	public static final String REQ_MESSAGE_TYPE_EVENT = "event";

	public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";

	public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";

	public static final String EVENT_TYPE_CLICK = "CLICK";
	
	public static final String EVENT_TYPE_SCAN = "SCAN";
	
	public static final String EVENT_TYPE_SHAKE_AROUND = "ShakearoundUserShake";

	/*@SuppressWarnings("unchecked")
	public static WechatMpMessage parseXml(HttpServletRequest request)
			throws Exception {
		return parseXml(request.getInputStream());
	}*/

	public static WechatMpMessage parseXml(InputStream inputStream) throws Exception {

		// 读取输入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		inputStream.close();
		inputStream = null;
		return parseXml(document);
	}

	public static WechatMpMessage parseXml(Document document) throws Exception {
		// 解析结果
		WechatMpMessage wechatMpMessage = new WechatMpMessage();

		Element root = document.getRootElement();
		// 得到根元素的所有子节点
		List<Element> elementList = root.elements();
		for (Element e : elementList) {
			if (e.elements().size() > 0) {
				if ("ChosenBeacon".equals(e.getName())) {
					//JSONObject json = new JSONObject();
					for (Object eo : e.elements()){
						Element e1 = (Element)eo;
						//json.put(e1.getName(), e1.getText());
						wechatMpMessage.setField(e1.getName(), e1.getText());
					};
					//map.put("ChosenBeacon", json.toJSONString());
				}
			} else {
				//map.put(e.getName(), e.getText());
				wechatMpMessage.setField(e.getName(), e.getText());
			}
		}
		return wechatMpMessage;
	}


	public static String textMessageToXml(TextMessage textMessage) {
		xstream.alias("xml", textMessage.getClass());
		return xstream.toXML(textMessage);
	}

	public static String musicMEssageToXml(MusicMessage musicMessage) {
		xstream.alias("xml", musicMessage.getClass());
		return xstream.toXML(musicMessage);
	}

	public static String newsMessageToXml(NewsMessage newsMessage) {
		xstream.alias("xml", newsMessage.getClass());
		return xstream.toXML(newsMessage).replace("com.dddj.resp.Article", "item");
	}

	public static <T extends BaseMessage> String wechatMsgToXml(T msg) {
		xstream.alias("xml", msg.getClass());
		return xstream.toXML(msg);
	}

	private static XStream xstream = new XStream(new XppDriver() {
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				// 对所有节点的转换都增加CDATA标记
				boolean cdata = true;

				@SuppressWarnings("rawtypes")
				public void startNode(String name, Class clazz) {
					super.startNode(name, clazz);
				}

				
				
				/*@Override
				protected void writeText(QuickWriter writer, String text) {
					if (cdata) {
						try {
							Long.parseLong(text);
							super.writeText(writer, text);
						} catch (Exception e) {
							writer.write("<![CDATA[");
							writer.write(text);
							writer.write("]]");
						}
						
					} else {
						super.writeText(writer, text);
					}
					
				}*/

				@SuppressWarnings("unused")
				protected void writerText(QuickWriter writer, String text) {
					if (cdata) {
						writer.write("<![CDATA[");
						writer.write(text);
						writer.write("]]");
					} else {
						writer.write(text);
					}
				}
			};
		}
	});
}
